package com.digicom.service.interaction.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.digicom.common.constant.Constants;
import com.digicom.common.entity.Article;
import com.digicom.common.entity.Comment;
import com.digicom.common.entity.Interaction;
import com.digicom.service.article.ArticleService;
import com.digicom.service.comment.CommentService;
import com.digicom.service.interaction.InteractionService;
import com.digicom.service.mapper.InteractionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 互动服务实现类
 */
@Slf4j
@Service
public class InteractionServiceImpl extends ServiceImpl<InteractionMapper, Interaction> implements InteractionService {

    @Autowired
    private InteractionMapper interactionMapper;

    @Autowired
    private ArticleService articleService;

    @Autowired
    private CommentService commentService;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 点赞文章
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean likeArticle(Long userId, Long articleId, String clientType) {
        try {
            // 检查文章是否存在
            Article article = articleService.getById(articleId);
            if (article == null) {
                log.error("点赞失败，文章不存在，articleId={}", articleId);
                return false;
            }

            // 检查用户是否已点赞
            if (checkUserLiked(userId, articleId)) {
                log.info("用户已点赞，无需重复操作，userId={}，articleId={}", userId, articleId);
                return true;
            }

            // 创建互动记录
            Interaction interaction = new Interaction();
            interaction.setUserId(userId);
            interaction.setArticleId(articleId);
            interaction.setInteractionType(Constants.INTERACTION_TYPE_LIKE);
            interaction.setClientType(clientType);
            interaction.setCreateTime(new Date());

            // 保存互动记录
            boolean result = save(interaction);
            if (result) {
                // 更新文章点赞计数
                updateArticleLikeCount(articleId, 1);
                
                // 更新缓存
                String key = getInteractionRedisKey(userId, articleId, Constants.INTERACTION_TYPE_LIKE);
                redisTemplate.opsForValue().set(key, true, 1, TimeUnit.DAYS);
            }
            
            return result;
        } catch (Exception e) {
            log.error("点赞操作异常", e);
            throw e;
        }
    }

    /**
     * 取消点赞
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelLike(Long userId, Long articleId) {
        try {
            // 检查用户是否已点赞
            if (!checkUserLiked(userId, articleId)) {
                return true;
            }

            // 删除互动记录
            LambdaQueryWrapper<Interaction> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Interaction::getUserId, userId)
                   .eq(Interaction::getArticleId, articleId)
                   .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_LIKE);
            
            boolean result = remove(wrapper);
            if (result) {
                // 更新文章点赞计数
                updateArticleLikeCount(articleId, -1);
                
                // 删除缓存
                String key = getInteractionRedisKey(userId, articleId, Constants.INTERACTION_TYPE_LIKE);
                redisTemplate.delete(key);
            }
            
            return result;
        } catch (Exception e) {
            log.error("取消点赞操作异常", e);
            throw e;
        }
    }

    /**
     * 收藏文章
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean collectArticle(Long userId, Long articleId, String clientType) {
        try {
            // 检查文章是否存在
            Article article = articleService.getById(articleId);
            if (article == null) {
                log.error("收藏失败，文章不存在，articleId={}", articleId);
                return false;
            }

            // 检查用户是否已收藏
            if (checkUserCollected(userId, articleId)) {
                log.info("用户已收藏，无需重复操作，userId={}，articleId={}", userId, articleId);
                return true;
            }

            // 创建互动记录
            Interaction interaction = new Interaction();
            interaction.setUserId(userId);
            interaction.setArticleId(articleId);
            interaction.setInteractionType(Constants.INTERACTION_TYPE_COLLECT);
            interaction.setClientType(clientType);
            interaction.setCreateTime(new Date());

            // 保存互动记录
            boolean result = save(interaction);
            if (result) {
                // 更新文章收藏计数
                updateArticleCollectCount(articleId, 1);
                
                // 更新缓存
                String key = getInteractionRedisKey(userId, articleId, Constants.INTERACTION_TYPE_COLLECT);
                redisTemplate.opsForValue().set(key, true, 1, TimeUnit.DAYS);
            }
            
            return result;
        } catch (Exception e) {
            log.error("收藏操作异常", e);
            throw e;
        }
    }

    /**
     * 取消收藏
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelCollect(Long userId, Long articleId) {
        try {
            // 检查用户是否已收藏
            if (!checkUserCollected(userId, articleId)) {
                return true;
            }

            // 删除互动记录
            LambdaQueryWrapper<Interaction> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Interaction::getUserId, userId)
                   .eq(Interaction::getArticleId, articleId)
                   .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_COLLECT);
            
            boolean result = remove(wrapper);
            if (result) {
                // 更新文章收藏计数
                updateArticleCollectCount(articleId, -1);
                
                // 删除缓存
                String key = getInteractionRedisKey(userId, articleId, Constants.INTERACTION_TYPE_COLLECT);
                redisTemplate.delete(key);
            }
            
            return result;
        } catch (Exception e) {
            log.error("取消收藏操作异常", e);
            throw e;
        }
    }

    /**
     * 分享文章
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean shareArticle(Long userId, Long articleId, String clientType) {
        try {
            // 检查文章是否存在
            Article article = articleService.getById(articleId);
            if (article == null) {
                log.error("分享失败，文章不存在，articleId={}", articleId);
                return false;
            }

            // 创建互动记录
            Interaction interaction = new Interaction();
            interaction.setUserId(userId);
            interaction.setArticleId(articleId);
            interaction.setInteractionType(Constants.INTERACTION_TYPE_SHARE);
            interaction.setClientType(clientType);
            interaction.setCreateTime(new Date());

            // 保存互动记录
            boolean result = save(interaction);
            if (result) {
                // 更新文章分享计数
                updateArticleShareCount(articleId, 1);
            }
            
            return result;
        } catch (Exception e) {
            log.error("分享操作异常", e);
            throw e;
        }
    }

    /**
     * 获取用户点赞的文章列表
     */
    @Override
    public Page<Interaction> listUserLiked(Long userId, Page<Interaction> page) {
        LambdaQueryWrapper<Interaction> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Interaction::getUserId, userId)
               .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_LIKE)
               .orderByDesc(Interaction::getCreateTime);
        
        return page(page, wrapper);
    }

    /**
     * 获取用户收藏的文章列表
     */
    @Override
    public Page<Interaction> listUserCollected(Long userId, Page<Interaction> page) {
        LambdaQueryWrapper<Interaction> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Interaction::getUserId, userId)
               .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_COLLECT)
               .orderByDesc(Interaction::getCreateTime);
        
        return page(page, wrapper);
    }

    /**
     * 检查用户是否点赞文章
     */
    @Override
    public boolean checkUserLiked(Long userId, Long articleId) {
        // 先从缓存中查询
        String key = getInteractionRedisKey(userId, articleId, Constants.INTERACTION_TYPE_LIKE);
        Object cached = redisTemplate.opsForValue().get(key);
        if (cached != null) {
            return (Boolean) cached;
        }
        
        // 缓存未命中，从数据库查询
        LambdaQueryWrapper<Interaction> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Interaction::getUserId, userId)
               .eq(Interaction::getArticleId, articleId)
               .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_LIKE);
        
        long count = count(wrapper);
        boolean result = count > 0;
        
        // 将结果存入缓存
        redisTemplate.opsForValue().set(key, result, 1, TimeUnit.DAYS);
        
        return result;
    }

    /**
     * 检查用户是否收藏文章
     */
    @Override
    public boolean checkUserCollected(Long userId, Long articleId) {
        // 先从缓存中查询
        String key = getInteractionRedisKey(userId, articleId, Constants.INTERACTION_TYPE_COLLECT);
        Object cached = redisTemplate.opsForValue().get(key);
        if (cached != null) {
            return (Boolean) cached;
        }
        
        // 缓存未命中，从数据库查询
        LambdaQueryWrapper<Interaction> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Interaction::getUserId, userId)
               .eq(Interaction::getArticleId, articleId)
               .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_COLLECT);
        
        long count = count(wrapper);
        boolean result = count > 0;
        
        // 将结果存入缓存
        redisTemplate.opsForValue().set(key, result, 1, TimeUnit.DAYS);
        
        return result;
    }

    /**
     * 获取文章互动统计数据
     */
    @Override
    public InteractionStatistic getArticleInteractionStats(Long articleId) {
        InteractionStatistic stats = new InteractionStatistic();
        
        // 从缓存获取统计数据
        String cacheKey = "article:stats:" + articleId;
        Object cachedStats = redisTemplate.opsForValue().get(cacheKey);
        if (cachedStats != null) {
            return (InteractionStatistic) cachedStats;
        }
        
        // 缓存未命中，从数据库查询
        try {
            // 获取点赞数
            LambdaQueryWrapper<Interaction> likeWrapper = new LambdaQueryWrapper<>();
            likeWrapper.eq(Interaction::getArticleId, articleId)
                      .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_LIKE);
            int likeCount = Math.toIntExact(count(likeWrapper));
            stats.setLikeCount(likeCount);
            
            // 获取收藏数
            LambdaQueryWrapper<Interaction> collectWrapper = new LambdaQueryWrapper<>();
            collectWrapper.eq(Interaction::getArticleId, articleId)
                         .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_COLLECT);
            int collectCount = Math.toIntExact(count(collectWrapper));
            stats.setCollectCount(collectCount);
            
            // 获取分享数
            LambdaQueryWrapper<Interaction> shareWrapper = new LambdaQueryWrapper<>();
            shareWrapper.eq(Interaction::getArticleId, articleId)
                       .eq(Interaction::getInteractionType, Constants.INTERACTION_TYPE_SHARE);
            int shareCount = Math.toIntExact(count(shareWrapper));
            stats.setShareCount(shareCount);
            
            // 获取评论数
            int commentCount = commentService.countArticleComments(articleId);
            stats.setCommentCount(commentCount);
            
            // 缓存统计结果，过期时间30分钟
            redisTemplate.opsForValue().set(cacheKey, stats, 30, TimeUnit.MINUTES);
            
            return stats;
        } catch (Exception e) {
            log.error("获取文章互动统计数据异常，articleId={}", articleId, e);
            
            // 发生异常时返回空对象
            stats.setLikeCount(0);
            stats.setCollectCount(0);
            stats.setShareCount(0);
            stats.setCommentCount(0);
            
            return stats;
        }
    }
    
    /**
     * 更新文章点赞计数
     */
    private void updateArticleLikeCount(Long articleId, int delta) {
        try {
            // 使用 Redis 缓存计数，定期同步到数据库
            String key = "article:like_count:" + articleId;
            redisTemplate.opsForValue().increment(key, delta);
            
            // 更新文章表中的点赞数
            articleService.updateLikeCount(articleId, delta);
        } catch (Exception e) {
            log.error("更新文章点赞数异常，articleId={}", articleId, e);
        }
    }
    
    /**
     * 更新文章收藏计数
     */
    private void updateArticleCollectCount(Long articleId, int delta) {
        try {
            // 使用 Redis 缓存计数，定期同步到数据库
            String key = "article:collect_count:" + articleId;
            redisTemplate.opsForValue().increment(key, delta);
            
            // 更新文章表中的收藏数
            articleService.updateCollectCount(articleId, delta);
        } catch (Exception e) {
            log.error("更新文章收藏数异常，articleId={}", articleId, e);
        }
    }
    
    /**
     * 更新文章分享计数
     */
    private void updateArticleShareCount(Long articleId, int delta) {
        try {
            // 使用 Redis 缓存计数，定期同步到数据库
            String key = "article:share_count:" + articleId;
            redisTemplate.opsForValue().increment(key, delta);
            
            // 更新文章表中的分享数
            articleService.updateShareCount(articleId, delta);
        } catch (Exception e) {
            log.error("更新文章分享数异常，articleId={}", articleId, e);
        }
    }
    
    /**
     * 获取互动Redis缓存键
     */
    private String getInteractionRedisKey(Long userId, Long articleId, String type) {
        return "user:interaction:" + userId + ":" + articleId + ":" + type;
    }
} 